import { CanActivate, ExecutionContext, HttpException, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { Request } from 'express';
import { Observable } from 'rxjs';
import { UserService } from '../user/user.service';
import { JwtService } from '@nestjs/jwt';
import { Reflector } from '@nestjs/core';
import { RedisService } from 'src/redis/redis.service';

@Injectable()
export class PermissionGuard implements CanActivate {
  @Inject(RedisService)
  private redisService: RedisService;

  @Inject(Reflector)
  private reflector: Reflector;

  @Inject(UserService) 
  private userService: UserService;

  @Inject(JwtService) 
  private jwtService: JwtService;

  async canActivate(
    context: ExecutionContext,
  ): Promise<boolean> {
    const request: Request = context.switchToHttp().getRequest();
    const token = request.header('authorization') || '';
    if(!token) {
      throw new HttpException('用户没有登陆', 403);
    }
    const tokenDecodeInfo = this.jwtService.decode(token); // 解析token，获取用户信息

    let permissions = await this.redisService.listGet(`user_${tokenDecodeInfo.username}_permissions`); 

    if(permissions.length === 0) {
      const foundUser = await this.userService.findByUsername(tokenDecodeInfo.username);
      permissions = foundUser.permissions.map(item => item.name);
      this.redisService.listSet(`user_${tokenDecodeInfo.username}_permissions`, permissions, 60 * 30)
    }

    const permission = this.reflector.get('permission', context.getHandler());

    if(permissions.some(item => item === permission)) {
      return true;
    } else {
      throw new HttpException('没有权限访问该接口', 403);
    }
  }
}

